package cn.js.sangu.unitStore.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.util.StrUtil;
import cn.js.sangu.unitStore.common.LogType;
import cn.js.sangu.unitStore.common.MyLogsAOP;
import cn.js.sangu.unitStore.common.R;
import cn.js.sangu.unitStore.common.exception.ServiceException;
import cn.js.sangu.unitStore.entity.CodeLib;
import cn.js.sangu.unitStore.entity.ExcelData;
import cn.js.sangu.unitStore.entity.User;
import cn.js.sangu.unitStore.service.CodeLibService;
import cn.js.sangu.unitStore.service.UserService;
import cn.js.sangu.unitStore.service.process.AutoCodeProcessService;
import cn.js.sangu.unitStore.service.process.ExcelProcessService;
import cn.js.sangu.unitStore.utils.TokenUtils;

@RestController
@RequestMapping("/codelib")
public class CodeLibController {

    static final String OPERATION_CODELIB = "历史码库";

    @Autowired
    CodeLibService codeLibService;

    @Autowired
    UserService userService;

    @Autowired
    ExcelProcessService excelProcessService;

    @MyLogsAOP(operation = OPERATION_CODELIB, operaType = LogType.LOOKUP)
    @GetMapping("findAll")
    public R findAll(@RequestParam String tuhao,
            @RequestParam String creator,
            @RequestParam String name,
            @RequestParam String bianma,
            @RequestParam String syscode) {
        QueryWrapper<CodeLib> wrapper = createQueryWrapper(tuhao, creator, name, bianma, syscode);

        List<CodeLib> list = null;
        try {
            wrapper.orderByAsc("id");
            list = codeLibService.list(wrapper);
        } catch (DataAccessException e) {
            throw new ServiceException("SQL语法出现错误");
        } catch (Exception e) {
            throw new ServiceException("系统接口出现错误，请联系管理员，错误码:500");
        }

        return R.ok(suppleName(list));
    }

    @MyLogsAOP(operation = OPERATION_CODELIB, operaType = LogType.LOOKUP)
    @GetMapping("findByPage")
    public R findByPage(@RequestParam Integer pageNum,
            @RequestParam Integer pageSize,
            @RequestParam String tuhao,
            @RequestParam String creator,
            @RequestParam String name,
            @RequestParam String bianma,
            @RequestParam String syscode) {
        QueryWrapper<CodeLib> wrapper = createQueryWrapper(tuhao, creator, name, bianma, syscode);

        // 构建page对象
        Page<CodeLib> param = new Page<>(pageNum, pageSize);

        Page<CodeLib> res = null;
        try {
            // 为分页查询也添加按id升序排序
            wrapper.orderByAsc("id");
            res = codeLibService.page(param, wrapper);
        } catch (DataAccessException e) {
            throw new ServiceException("SQL语法出现错误");
        } catch (Exception e) {
            throw new ServiceException("系统接口出现错误，请联系管理员，错误码:500");
        }
        return R.ok(res.setRecords(suppleName(res.getRecords())));
    }

    /**
     * 创建查询条件包装器
     * 
     * @param tuhao   图号
     * @param creator 创建人
     * @param name    名称
     * @param bianma  人工编码
     * @param syscode 系统编码
     * @return 查询条件包装器
     */
    private QueryWrapper<CodeLib> createQueryWrapper(String tuhao, String creator, String name, String bianma,
            String syscode) {
        QueryWrapper<CodeLib> wrapper = new QueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(tuhao), "tuhao", tuhao);
        wrapper.like(StrUtil.isNotBlank(creator), "creator", creator);
        wrapper.like(StrUtil.isNotBlank(name), "name", name);
        wrapper.like(StrUtil.isNotBlank(bianma), "bianma", bianma);
        wrapper.like(StrUtil.isNotBlank(syscode), "syscode", syscode);
        // 移除降序排序设置，让调用方决定排序方式
        return wrapper;
    }

    /**
     * 补充创建人+修改人+接收人 名称
     * 
     * @param list
     * @return
     */
    private List<CodeLib> suppleName(List<CodeLib> list) {
        for (CodeLib item : list) {
            // 创建人
            User author = userService.getById(item.getCreator());
            if (null != author)
                item.setCreatorName(author.getName());
            // 修改人
            User modifier = userService.getById(item.getModifier());
            if (null != modifier)
                item.setModifierName(modifier.getName());
        }
        return list;
    }

    /**
     * 删除码库记录
     * 
     * @param id 记录ID
     * @return 操作结果
     */
    @MyLogsAOP(operation = OPERATION_CODELIB, operaType = LogType.DELETE)
    @DeleteMapping("delete/{id}")
    public R deleteById(@PathVariable Integer id) {
        try {
            // 验证ID是否存在
            CodeLib codeLib = codeLibService.getById(id);
            if (codeLib == null) {
                return R.fail("记录不存在");
            }

            boolean success = codeLibService.removeById(id);
            if (success) {
                return R.ok("删除成功");
            } else {
                return R.fail("删除失败，请重试");
            }
        } catch (DataAccessException e) {
            throw new ServiceException("SQL语法出现错误");
        } catch (Exception e) {
            throw new ServiceException("系统接口出现错误，请联系管理员，错误码:500");
        }
    }

    /**
     * 批量删除码库记录
     * 
     * @param ids 记录ID列表
     * @return 操作结果
     */
    @MyLogsAOP(operation = OPERATION_CODELIB, operaType = LogType.DELETE)
    @DeleteMapping("deleteBatch")
    public R deleteBatch(@RequestBody List<Integer> ids) {
        try {
            // 验证ID列表
            if (ids == null || ids.isEmpty()) {
                return R.fail("请选择要删除的记录");
            }

            // 检查是否存在无效记录
            long count = codeLibService.count(new QueryWrapper<CodeLib>().in("id", ids));
            if (count < ids.size()) {
                return R.fail("部分记录不存在，请刷新后重试");
            }

            boolean success = codeLibService.removeByIds(ids);
            if (success) {
                return R.ok("批量删除成功");
            } else {
                return R.fail("批量删除失败，请重试");
            }
        } catch (DataAccessException e) {
            throw new ServiceException("SQL语法出现错误");
        } catch (Exception e) {
            throw new ServiceException("系统接口出现错误，请联系管理员，错误码:500");
        }
    }

    /**
     * 清空全部码库记录
     * 
     * @return 操作结果
     */
    @MyLogsAOP(operation = OPERATION_CODELIB, operaType = LogType.DELETE)
    @DeleteMapping("deleteAll")
    public R deleteAll() {
        try {
            // 先统计记录数，便于日志和返回信息
            long countBefore = codeLibService.count();

            if (countBefore == 0) {
                return R.ok("当前没有可清空的数据");
            }

            // 执行清空操作：使用truncate table代替delete操作
            codeLibService.getBaseMapper().truncateTable();
            boolean success = true; // truncate操作成功执行

            if (success) {
                return R.ok("清空全部数据成功，共删除 " + countBefore + " 条记录");
            } else {
                return R.fail("清空全部数据失败，请重试");
            }
        } catch (DataAccessException e) {
            throw new ServiceException("SQL语法出现错误，清空操作失败");
        } catch (Exception e) {
            throw new ServiceException("系统接口出现错误，请联系管理员，错误码:500");
        }
    }

    /**
     * 保存码库记录
     * 
     * @param codeLib 码库记录对象
     * @return 操作结果
     */
    @MyLogsAOP(operation = OPERATION_CODELIB, operaType = LogType.ADD)
    @PostMapping("save")
    public R save(@RequestBody CodeLib codeLib) {
        try {
            // 验证参数
            if (codeLib == null) {
                return R.fail("提交数据不能为空");
            }

            // 创建ExcelData对象用于生成系统编码
            ExcelData data = new ExcelData();
            data.setTuhao(codeLib.getTuhao());
            data.setName(codeLib.getName());
            data.setCailiao(codeLib.getCailiao());
            data.setGuige(codeLib.getGuige());
            data.setLeibie(codeLib.getLeibie());
            data.setBianma(codeLib.getBianma());

            // 获取当前用户信息
            User currentUser = TokenUtils.getCurrentUser();
            Integer currentUserId = currentUser != null ? currentUser.getId() : null;

            // 生成系统编码
            String syscode = excelProcessService.autocode(data, currentUserId, "手动新增");

            // 验证系统编码生成是否成功
            if (StrUtil.isBlank(syscode)) {
                return R.fail("系统编码生成失败，请重试");
            } else {
                return R.ok("保存成功");
            }
        } catch (DataAccessException e) {
            throw new ServiceException("SQL语法出现错误");
        } catch (Exception e) {
            throw new ServiceException("系统接口出现错误，请联系管理员，错误码:500");
        }
    }
}
